home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / C / LIB / EXPRO / _files / _exprodir / exprofle._c < prev    next >
Text File  |  1990-06-04  |  6KB  |  198 lines

  1.  
  2. /*
  3.  *  exprofle.c
  4.  *
  5.  *  version 1.00, 04-06-1990
  6.  *
  7.  *  execution profiler
  8.  *
  9.  *  copyright Ferdinand Oeinck 1990
  10.  *
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <stdlib.h>
  16. #include "h.swis"
  17. #include "kernel.h"
  18. #include "h.exproasm"
  19.  
  20.  
  21. int * funcadr_ptr;
  22. int * count_ptr;
  23. int funccount;
  24. static char * filen;
  25.  
  26. void myexithandler(void);
  27.  
  28.  
  29. void exprofle_init(char * filename)
  30. {
  31.  unsigned int * codestart;
  32.  unsigned int * codeend;
  33.  unsigned int * i;
  34.  int fpestart, fpeend;
  35.  int len, instr, count = 0;
  36.  _kernel_swi_regs regs;
  37.  char * modulename;
  38.  
  39.  if (_kernel_hostos() != _kernel_ARTHUR) {
  40.     printf("Error: Not running on ARTHUR host OS\n");
  41.     exit(1);
  42.  }
  43.  if (!_kernel_fpavailable()) {
  44.     printf("Warning: Execution time profiling not possible.\n");
  45.     printf("         No floating point support.\n");
  46.     return;
  47.  }
  48.  regs.r[0] = 12;
  49.  regs.r[1] = 0;
  50.  regs.r[2] = 0;
  51.  while (_kernel_swi(OS_Module, ®s, ®s) == NULL) {
  52.        modulename = (char*)(regs.r[3] + *((int *)(regs.r[3] + 0x10)));
  53.        if (strcmp(modulename,"FPEmulator") == 0) break;
  54.  }
  55.  fpestart = regs.r[3];
  56.  _kernel_swi(OS_Module, ®s, ®s);
  57.  fpeend = regs.r[3];
  58.  
  59.  if ( (filen = malloc(strlen(filename) + 1)) == NULL) {
  60.     printf("Warning: Execution time profiling not possible.\n");
  61.     printf("         Malloc failed.\n");
  62.     return;
  63.  }
  64.  
  65.  strcpy(filen, filename);
  66.  
  67.  codestart = exproasm_getstart();
  68.  codeend = exproasm_getend();
  69.  
  70.  for (i = codestart; i != codeend; i++) {
  71.      instr = *i & 0xffff0000;
  72.      if (instr == (unsigned int) 0xff000000) {
  73.         len = *i & 0xffff;
  74.         if (len >= strlen((char *)i - len)) count++;
  75.      }
  76.  }
  77.  count += 4;
  78.  
  79.  if ((funcadr_ptr = (int *) calloc(count, sizeof(int))) == NULL) {
  80.     printf("Warning: Execution time profiling not possible.\n");
  81.     printf("         Malloc failed.\n");
  82.     free(filen);
  83.     return;
  84.  }
  85.  if ((count_ptr   = (int *) calloc(count, sizeof(int))) == NULL) {
  86.     printf("Warning: Execution time profiling not possible.\n");
  87.     printf("         Malloc failed.\n");
  88.     free(funcadr_ptr);
  89.     free(filen);
  90.     return;
  91.  }
  92.  funccount = count;
  93.  
  94.  count = 1;
  95.  for (i = codestart; i != codeend; i++) {
  96.      instr = *i & 0xffff0000;
  97.      if (instr == (unsigned int) 0xff000000) {
  98.         len = *i & 0xffff;
  99.         if (len >= strlen((char *)i - len)) {
  100.            funcadr_ptr[count++] = (int) i - len;
  101.         }
  102.      }
  103.  }
  104.  funcadr_ptr[count]     = (int) codeend;
  105.  funcadr_ptr[count + 1] = (int) fpestart;
  106.  funcadr_ptr[count + 2] = (int) fpeend;
  107.  
  108.  if (!exproasm_ClaimIntDeviceVector()) {
  109.     free(count_ptr);
  110.     free(funcadr_ptr);
  111.     free(filen);
  112.     printf("Warning: Execution time profiling not possible.\n");
  113.     printf("         I think this is not RISC_OS 2.00\n");
  114.     return;
  115.  }
  116.  atexit(myexithandler);
  117. }
  118.  
  119. void myexithandler(void)
  120. {
  121.  int i, sumc = 0;
  122.  float sum = 0, sump = 0;
  123.  FILE *fp;
  124.  exproasm_ReleaseIntDeviceVector();
  125.  
  126.  for (i = 0; i < funccount; i++) sum += count_ptr[i];
  127.  sum = sum - count_ptr[funccount - 2];  /* substract double counted fp values */
  128.  if (sum == 0) sum = 1;
  129.  
  130.  fp = fopen(filen, "w");
  131.  
  132.  fprintf(fp, "  nr   address  function name                         percentage    count\n");
  133.  fprintf(fp, "==========================================================================\n");
  134.  
  135.  fprintf(fp, "%4i %8x:  %-40s: %6.2f, %7i\n", 0,
  136.          funcadr_ptr[1], "lessthan", 100.0 * (float) count_ptr[0] / sum, count_ptr[0]);
  137.  sump += (float) 100.0 * (float) count_ptr[0] / sum;
  138.  sumc += count_ptr[0];
  139.  
  140.  for (i = 1 ; i < funccount - 3; i++) {
  141.     fprintf(fp, "%4i %8x:  %-40s: %6.2f, %7i\n", i, funcadr_ptr[i],
  142.             (char *)funcadr_ptr[i], 100.0 * (float) count_ptr[i] / sum, count_ptr[i]);
  143.     sump +=  (float) 100.0 * (float) count_ptr[i] / sum;
  144.     sumc += count_ptr[i];
  145.  }
  146.  fprintf(fp, "%4i %8x:  %-40s: %6.2f, %7i\n", funccount-3, funcadr_ptr[funccount-3],
  147.          "greaterthan", 100.0 * (float) count_ptr[funccount-3] / sum,
  148.          count_ptr[funccount-3]);
  149.  sump += (float) 100.0 * (float) count_ptr[funccount-3] / sum;
  150.  sumc += count_ptr[funccount - 3];
  151.  
  152.  fprintf(fp, "==========================================================================\n");
  153.  fprintf(fp, "                                                          %6.2f, %7i\n",
  154.          sump, sumc);
  155.  fprintf(fp, "percentage of time spent in fpemulator\n");
  156.  fprintf(fp, "%4i %8x:  %-40s: %6.2f, %7i\n", funccount-2, funcadr_ptr[funccount-2],
  157.          "fpemulator", 100.0 * (float) count_ptr[funccount-2] / sum,
  158.          count_ptr[funccount-2]);
  159.  
  160.  fclose(fp);
  161.  free(count_ptr);
  162.  free(funcadr_ptr);
  163.  free(filen);
  164. }
  165.  
  166. /* this function is called every 1/100 seconds */
  167.  
  168. void binsearch(int *adr)
  169. {
  170.     /* binary search of address table */
  171.     int high = funccount - 1;
  172.     int low = 1;
  173.     extern int expro_fp_return_address;
  174.  
  175.     if ((int) adr < (int) funcadr_ptr[1]) { ++count_ptr[0]; return; }
  176.     if ((int) adr > (int) funcadr_ptr[funccount-2] &&
  177.         (int) adr <= (int) funcadr_ptr[funccount-1]) {
  178.         ++count_ptr[funccount-2];         /* we are in the fpemulator */
  179.         adr = (int*) expro_fp_return_address;    /* so use that return address */
  180.     }
  181.     if ((int) adr > (int) funcadr_ptr[funccount-3]) {
  182.        ++count_ptr[funccount-3];
  183.        return;
  184.     }
  185.     while((high - low) > 1){
  186.         int middle = (high + low) / 2;
  187.         if ((int)adr > (int)funcadr_ptr[middle] && (int)adr < (int)funcadr_ptr[middle + 1]) {
  188.            low = middle;
  189.            break;
  190.         }
  191.         if ((int)adr > (int)funcadr_ptr[middle+1])
  192.             low = middle + 1;
  193.         else
  194.             high = middle;
  195.     }
  196.     ++count_ptr[low];
  197. }
  198.